package com.hfb.mashibing.alip8.spring.shardingsphere.config;

import com.alibaba.druid.pool.DruidDataSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

/**
 * 多数据源配置
 */
@Data
@Slf4j
@Configuration
@PropertySource("classpath:config/datasources.properties")
@ConfigurationProperties(prefix = "spring")
public class DataSources {

    private DataSourceConfig dataSource01;
    private DataSourceConfig dataSource02;
    private DataSourceConfig dataSource03;


    private static List<DataSource> dataSources = new ArrayList<>();

    public static int getDataSourceSize() {
        log.debug("dataSources.size():{}",dataSources.size());
        return dataSources.size();
    }

    @Bean
    public List<DataSource> ds(){
        dataSources.add(buildDruidDataSource(dataSource01));
        dataSources.add(buildDruidDataSource(dataSource02));
        dataSources.add(buildDruidDataSource(dataSource03));
        return dataSources;
    }

    private DruidDataSource buildDruidDataSource(DataSourceConfig dataSource) {
        return DataSourceBuilder.create()
                .type(DruidDataSource.class)
                .driverClassName(dataSource.getDriverClassName())
                .url(dataSource.getUrl())
                .username(dataSource.getUsername())
                .password(dataSource.getPassword())
                .build();
    }

    @Bean
    @Primary
    public DataSourceRouter routingDataSource(){
        List<DataSource> dataSources = ds();

        Map<Object,Object> targetDataSources = new HashMap<Object, Object>(){{
            put(DataSourceContextHolder.DATA_SOURCE_01,dataSources.get(0));
            put(DataSourceContextHolder.DATA_SOURCE_02,dataSources.get(1));
            put(DataSourceContextHolder.DATA_SOURCE_03,dataSources.get(2));
        }};

        DataSourceRouter routerDataSource = new DataSourceRouter();
        routerDataSource.setTargetDataSources(targetDataSources);
        routerDataSource.setDefaultTargetDataSource(dataSources.get((0)));
        return routerDataSource;
    }

    /**
     * 设置事务，事务需要知道当前使用的是哪个数据源才能进项事务管理
     * @return
     */
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(){
        return new DataSourceTransactionManager(routingDataSource());
    }

}
